function Promise(exector) {
  var _this = this
  this.status = 'pending'
  this.value;
  this.resolveList = []
  this.rejectList = []

  try {
    exector(resolve, reject)
  } catch(e) {
    reject(e)
  }

  function resolve(value) {
    if(_this.status === 'pending') {
      _this.status = 'fulfilled'
      _this.value = value
      _this.resolveList.forEach(item => {
        item(_this.value)
        _this.resolveList.shift()
      })
    }
  }

  function reject(value) {
    if(_this.status === 'pending') {
      _this.status = 'rejected'
      _this.value = value
      _this.rejectList.forEach(item => {
        item(_this.value)
        _this.rejectList.shift()
      })
    }
  }
}

Promise.prototype.then = function(resolveCallback, rejectCallback) {
  var _this = this
  if(this.status === 'fulfilled') {
    return new Promise((resolve, reject) => {
      var result = resolveCallback(_this.value)
      if(result instanceof Promise) {
        result.then(resolve, reject)
      } else {
        resolve(result)
      }
    })
  }

  if(this.status === 'rejected') {
    return new Promise((resolve, reject) => {
      var result = rejectCallback(_this.value)
      if(result instanceof Promise) {
        result.then(resolve, reject)
      } else {
        resolve(result)
      }
    })
  }

  if(this.status === 'pending') {
    return new Promise((resolve, reject) => {
      this.resolveList.push(function() {
        var result = resolveCallback(_this.value)
        if(result instanceof Promise) {
          result.then(resolve, reject)
        } else {
          resolve(result)
        }
      })
      this.rejectList.push(function() {
        var result = rejectCallback(_this.value)
        if(result instanceof Promise) {
          result.then(resolve, reject)
        } else {
          resolve(result)
        }
      })
    })
  }

}

let promise = new Promise((resolve, reject) => {
  reject(666)
})

promise.then(data => {
  console.log(data)
  return data + 1
}, reason => {
  console.warn('reason', reason)
}).then(data => {
  console.log(data)
}, reason => {
  console.warn('reason', reason)
})
